Skip to main content

部署

(一)配置站点域名

Keycloak 强烈建议用独立子域名 auth.ordinis.dev,不要和主站(www.ordinis.dev)共用同一个域名与路径。

1. Cloudflare DNS

新增记录:

  • auth → A → 你的服务器 IP → Proxied(橙云)

image-20260109195331011

2. 部署 Nginx 站点

Nginx 进行转发: auth.ordinis.dev127.0.0.1:8081

创建站点配置:

sudo tee /etc/nginx/sites-available/auth.ordinis.dev > /dev/null <<'EOF'
server {
    listen 80;
    server_name auth.ordinis.dev;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name auth.ordinis.dev;

    ssl_certificate     /etc/nginx/ssl/ordinis.dev/origin-cert.pem;
    ssl_certificate_key /etc/nginx/ssl/ordinis.dev/origin-key.pem;

    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:8081;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Keycloak 对反代头比较敏感,建议加上:
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port 443;
    }
}
EOF

启用并重载:

sudo ln -sf /etc/nginx/sites-available/auth.ordinis.dev /etc/nginx/sites-enabled/auth.ordinis.dev
sudo nginx -t && sudo systemctl reload nginx

(二)安装 Docker

更新系统与安装依赖

sudo apt update && sudo apt -y upgrade
sudo apt -y install ca-certificates curl gnupg ufw

安装 Docker 与 Compose 插件

# 安装 Docker 官方源
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

确认 Docker / Compose 可用

docker --version
docker compose version
docker info | head

确认服务状态

sudo systemctl status docker --no-pager

清理掉“半装不装”的系统包(如果有)

只在你确实装过系统版 containerd/docker.io 的情况下做;你现在报错说明系统可能有 containerd 依赖链,但不一定已安装。可以先检查:

dpkg -l | egrep 'docker\.io|containerd($| )|runc'
  • 如果看到 docker.iocontainerd(注意不是 containerd.io),建议移除系统版,保持官方版:
sudo apt remove -y docker.io containerd runc
sudo apt autoremove -y

这不会影响你已经装好的 docker-ce / containerd.io,反而避免未来冲突。

你已经装的是 Docker 官方源,后续请用:

  • docker-ce
  • docker-ce-cli
  • containerd.io
  • docker-compose-plugin

不要再碰:

  • docker.io
  • containerd(系统版)

(三) 部署 Postgres + Keycloak

在服务器创建目录:

mkdir -p ~/keycloak && cd ~/keycloak

写入 docker-compose.yml,注意修改密码

services:
  db:
    image: postgres:16
    container_name: keycloak_db
    restart: unless-stopped
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: [此处为密码]
    volumes:
      - kc_pgdata:/var/lib/postgresql/data
    networks:
      - kcnet

  keycloak:
    image: quay.io/keycloak/keycloak:26.0
    container_name: keycloak
    restart: unless-stopped
    command: start --proxy-headers=xforwarded --http-enabled=true --hostname=auth.ordinis.dev
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://db:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: [此处为密码,注意和上面的 POSTGRES_PASSWORD 一样]
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: [此处为密码]
      
      KC_PROXY: edge
      KC_PROXY_HEADERS: xforwarded
      KC_HOSTNAME: auth.ordinis.dev
      KC_HOSTNAME_STRICT: "true"
      KC_HOSTNAME_STRICT_HTTPS: "true"
    depends_on:
      - db
    ports:
      - "127.0.0.1:8081:8080"
    networks:
      - kcnet

volumes:
  kc_pgdata:

networks:
  kcnet:

建议你把密码在 YAML 里用引号包起来,避免 YAML 解析边界问题:

POSTGRES_PASSWORD: "..."

启动:

docker compose up -d
docker compose ps

本机验证 Keycloak 是否起来:(注意启动后要等 3 分钟)

curl -I http://127.0.0.1:8081

返回内容应为:

HTTP/1.1 302 Found
Location: http://auth.ordinis.dev:8081/admin/
Referrer-Policy: no-referrer
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

浏览器打开:https://auth.ordinis.dev,用你在 compose 里设置的:admin / change_me_admin_password 登录 Keycloak 管理台:

image-20260109233427847

注:如果要修改密码/重新部署 → 删除旧数据库卷并重启

因为 Postgres 初始化密码只在首次创建数据卷时生效。你改 compose 但不删卷,数据库里仍是旧密码,会继续失败。

cd ~/keycloak
docker compose down
docker volume rm keycloak_kc_pgdata
docker compose up -d

显示日志

docker compose logs -n 50 keycloak
docker compose logs -n 50 db

如果你已经在库里有数据(通常你现在还没有),那就要进入 Postgres 容器里改密码:

docker exec -it keycloak_db psql -U keycloak -d keycloak

然后在 psql 里执行(把新密码换成你要的):

ALTER USER keycloak WITH PASSWORD '你的新密码';
\q

并确保 KC_DB_PASSWORD 也改成同一个新密码,然后:

docker compose restart keycloak


(四)新建安全账户

网页上登录后有一条警告:

You are logged in as a temporary admin user. To harden security, create a permanent admin account and delete the temporary one.

含义是你现在登录使用的是 启动时通过环境变量创建的临时管理员

KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=...

这个账号 仅用于 首次初始化 / 紧急访问, 不受 Keycloak 内部用户策略(MFA、角色审计、禁用等)完整管理,同时 通常会被扫描器重点尝试爆破(用户名固定)

Keycloak 的安全模型要求你 把“真正的管理员”放到 Realm 的用户体系里,而不是依赖这个 bootstrap 账号。


1. 创建新账号

Keycloak Admin Console 中:

  1. 进入 master Realm

  2. 左侧 Users → Create user

    注意:你现在创建的这个用户 = Keycloak 的“身份与权限管理用户”,并非是 业务用户(End User)

    image-20260109234516837

  3. 创建一个新用户,例如:

    • Username:ordinis-admin
    • Email:你的管理员邮箱
    • required user actions: 不选
    • 创建好之后为:
    • ![image-20260110000630642](/Users/heihe/Library/Application Support/typora-user-images/image-20260110000630642.png)
  4. 设置密码

    • CredentialsSet password
    • Temporary:OFF
  5. 授权

    • UsersheiheRole mapping

      此时应该只有一个 权限

      image-20260111235131576

    • 点击 Assign role - 左上角把筛选切到 Filter by clients - 全选 - Assign

      这里是该用户对 client 层面的管理能力,比如创建/删除 client,

      image-20260111235239888

    • 点击 Assign role - 左上角把筛选切到 Filter by clients - 全选 - Assign

      这里是该用户对 Realm 层面的管理能力,比如创建/删除 Realm

      image-20260111235430570

  6. 多重身份验证(可选)

  • Account → Security → 开启 OTP

    image-20260110001724785

  1. 手动进入控制台

    此时,进入 Application 界面,会只能看到这个控制台

    image-20260110002554240

    这个控制台是“账号私人控制台”,不是 “整个用户系统的管理界面”

    其 URL 是 https://auth.ordinis.dev/realms/master/account/

    需要我们手动登录 https://auth.ordinis.dev/admin/ 之后

    这里才会显示出两个控制台,其中上面一个才是整个用户系统的控制台

    image-20260110002808310

注:在 Create User 时,有要选择 user actions。其含义为这个用户“第一次登录时,必须被强制完成哪些动作”。它不是权限,也不是功能开关,而是登录流程控制。对于管理员而言,应该一个都不要选。

image-20260109234644501

  • Configure OTP(配置一次性验证码):第一次登录必须绑定 MFA(Google Authenticator 等)
  • Update Password:第一次登录必须改密码
  • Verify Email:必须点邮箱里的验证链接才能继续,如果你还没配置 SMTP,会直接卡死

  • Webauthn Register / Passwordless:强制注册硬件密钥 / 无密码登录

  • Update Profile / Verify Profile:强制用户补充个人信息


2. 删除临时 admin

确认新账号可用后:

  1. docker-compose.yml删除

    KEYCLOAK_ADMIN
    KEYCLOAK_ADMIN_PASSWORD
    
  2. 重启 Keycloak:

    docker compose restart keycloak
  3. 删除或禁用 admin

    在 Admin Console(master realm)里:

    选择 master realm → Users → 找到用户名 admin → 删除 admin 账号

    image-20260110004010880

    此时,我们就无法再使用 临时的 admin 账号登录了

额外检查:你有没有把“永久管理员”建在对的 Realm?

注意: Keycloak Admin Console 的管理权限通常在 master realm(尤其是你要管理整个 Keycloak 实例)。

你新建的永久管理员应该满足:

  • master realm 下创建
  • Role mapping 里有:
    • realm-managementrealm-admin

否则你可能误以为有永久管理员,但实际上只有 admin 真能管系统。